package com.gym.code.config.admin.client;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gym.code.config.admin.client.model.DBColumnModel;
import com.gym.code.config.admin.client.model.DBTableModel;

/**
 * 
 * @author xinchun.wang 
   @email: 532002108@qq.com
 * @createTime 2015-4-19 下午4:42:36
 */
public class TableUtils {
    private static final Logger logger = LoggerFactory.getLogger(TableUtils.class);
	 
	public static List<DBTableModel> getTableList(Connection connection)  {
		List<DBTableModel> tables = new ArrayList<DBTableModel>();
		try {
			ResultSet rs = null;
			// 所有表
			rs = connection.getMetaData().getTables(null, null, null, null);
			while (rs.next()) {
				DBTableModel t = new DBTableModel();
				t.setTableName(rs.getString("TABLE_NAME"));
				logger.info("tableName:{}", t.getTableName());
				tables.add(t);
			}
			rs.close();
			
			// 所有表中的列
			for (DBTableModel table : tables) {
				// 主键
				ResultSet rsp = connection.getMetaData().getPrimaryKeys(null, null, table.getTableName());
				List<String> pks = new ArrayList<String>();
				while (rsp.next()) {
					pks.add(rsp.getString("COLUMN_NAME"));
				}
				rsp.close();
				rsp = null;
				// 列
				rs = connection.getMetaData().getColumns(null, null, table.getTableName(), null);
				while (rs.next()) {
					DBColumnModel c = new DBColumnModel();
					c.setColumnName(rs.getString("COLUMN_NAME"));
					if (pks.contains(c.getColumnName())) {
						c.setPrimaryKey(true);
					}
					int dataType = rs.getInt("DATA_TYPE");
					c.setClz(toBeanType(dataType));
					int nullable = rs.getInt("NULLABLE");
					if (DatabaseMetaData.columnNullable == nullable) {
						// 明确指出可以为空
						c.setNullAble(true);
					} else {
						c.setNullAble(false);
					}
					c.setDefaultValue(rs.getString("COLUMN_DEF"));	// 默认值
					c.setAutoIncrement("YES".equals(rs.getString("IS_AUTOINCREMENT")));
					logger.info("tableName:{}; column:{}", table.getTableName(), c.getColumnName());
					table.getColumnList().add(c);
				}
				rs.close();
			}
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				connection.close();
			} catch (SQLException e) {
			}
		}
		return tables;
	}
	
	
	/**
	 * 转换bean需要的类型定义
	 * @param type
	 * @return
	 */
	private static Class<?> toBeanType(int type) {
		Class<?> clz = typesMap.get(type);
		return clz == null ? String.class : clz;
	}
	
	
	/** 数据库类型映射，保存非String类型的对应关系，其它类型默认String */
	private static Map<Integer, Class<?>> typesMap = new HashMap<Integer, Class<?>>();
	static {
		typesMap.put(java.sql.Types.BIGINT, Long.class);
		typesMap.put(java.sql.Types.BOOLEAN, Boolean.class);
		typesMap.put(java.sql.Types.DATE, Date.class);
		typesMap.put(java.sql.Types.DECIMAL, BigDecimal.class);
		typesMap.put(java.sql.Types.DOUBLE, Double.class);
		typesMap.put(java.sql.Types.FLOAT, Float.class);
		typesMap.put(java.sql.Types.INTEGER, Integer.class);
		typesMap.put(java.sql.Types.TINYINT, Integer.class);
		typesMap.put(java.sql.Types.NUMERIC, Number.class);
		typesMap.put(java.sql.Types.TIME, Date.class);
		typesMap.put(java.sql.Types.TIMESTAMP, Date.class);
	}
	
	
}
